package com.shanzhu.beadhouse.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shanzhu.beadhouse.common.constant.BedEnum;
import com.shanzhu.beadhouse.common.constant.ExceptionEnum;
import com.shanzhu.beadhouse.common.constant.YesNoEnum;
import com.shanzhu.beadhouse.common.util.AssertUtil;
import com.shanzhu.beadhouse.dao.mapper.BedMapper;
import com.shanzhu.beadhouse.entity.base.Result;
import com.shanzhu.beadhouse.entity.po.Bed;
import com.shanzhu.beadhouse.entity.po.Elder;
import com.shanzhu.beadhouse.entity.po.Building;
import com.shanzhu.beadhouse.entity.po.Floor;
import com.shanzhu.beadhouse.entity.po.Room;
import com.shanzhu.beadhouse.entity.query.BedManageQuery;
import com.shanzhu.beadhouse.entity.query.OperateBedQuery;
import com.shanzhu.beadhouse.entity.query.PageBedByKeyQuery;
import com.shanzhu.beadhouse.entity.vo.PageBedByKeyVo;
import com.shanzhu.beadhouse.service.BedManageService;
import com.shanzhu.beadhouse.service.common.BedFunc;
import com.shanzhu.beadhouse.service.common.ElderFunc;
import com.shanzhu.beadhouse.service.common.RoomFunc;
import com.shanzhu.beadhouse.service.common.BuildingFunc;
import com.shanzhu.beadhouse.service.common.FloorFunc;
import com.shanzhu.beadhouse.service.common.RoomTypeFunc;
import com.shanzhu.beadhouse.entity.base.DropDown;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class BedManageServiceImpl implements BedManageService {
    @Resource
    private BedMapper bedMapper;
    @Resource
    private BedFunc bedFunc;
    @Resource
    private ElderFunc elderFunc;
    @Resource
    private RoomFunc roomFunc;
    @Resource
    private BuildingFunc buildingFunc;
    @Resource
    private FloorFunc floorFunc;
    @Resource
    private RoomTypeFunc roomTypeFunc;

    @Override
    public Result pageBedByKey(BedManageQuery query) {
        System.out.println("BedManageServiceImpl.pageBedByKey - 开始处理请求，参数: " + query);
        
        // 获取所有相关数据
        List<Building> buildingList = buildingFunc.listNotDelBuilding();
        List<Floor> floorList = floorFunc.listNotDelFloor();
        List<Room> roomList = roomFunc.listNotDelRoom();
        List<Bed> bedList = bedFunc.listNotDelBed();
        List<Elder> elderList = elderFunc.listLiveElder(query.getElderName());
        
        System.out.println("BedManageServiceImpl.pageBedByKey - 数据获取完成:");
        System.out.println("  buildingList size: " + buildingList.size());
        System.out.println("  floorList size: " + floorList.size());
        System.out.println("  roomList size: " + roomList.size());
        System.out.println("  bedList size: " + bedList.size());
        System.out.println("  elderList size: " + elderList.size());

        // 创建PageBedByKeyQuery用于BedFunc过滤
        PageBedByKeyQuery filterQuery = new PageBedByKeyQuery();
        filterQuery.setBuildId(query.getBuildingId()); // 字段名转换
        filterQuery.setFloorId(query.getFloorId());
        filterQuery.setRoomId(query.getRoomId());
        filterQuery.setBedFlag(query.getBedFlag());
        filterQuery.setElderName(query.getElderName());
        
        System.out.println("BedManageServiceImpl.pageBedByKey - 过滤条件:");
        System.out.println("  buildId: " + filterQuery.getBuildId());
        System.out.println("  floorId: " + filterQuery.getFloorId());
        System.out.println("  roomId: " + filterQuery.getRoomId());
        System.out.println("  bedFlag: " + filterQuery.getBedFlag());
        System.out.println("  elderName: " + filterQuery.getElderName());

        // 使用BedFunc的过滤方法
        List<PageBedByKeyVo> filteredList = bedFunc.filterBedByKey(buildingList, floorList, roomList, bedList, filterQuery);
        
        System.out.println("BedManageServiceImpl.pageBedByKey - 过滤后结果:");
        System.out.println("  filteredList size: " + filteredList.size());

        // 关联老人信息
        for (PageBedByKeyVo vo : filteredList) {
            // 如果不是空闲状态，查找对应的老人
            if (!Objects.equals(vo.getBedFlag(), BedEnum.IDLE.getStatus())) {
                elderList.stream()
                        .filter(elder -> Objects.equals(elder.getBedId(), vo.getId()))
                        .findFirst()
                        .ifPresent(elder -> {
                            vo.setElderName(elder.getName());
                            vo.setSex(elder.getSex());
                            vo.setAge(elder.getAge());
                            // 由于数据库中没有入住时间字段，暂时设置为空
                            vo.setCheckInDate("");
                        });
            }
        }

        // 如果指定了老人姓名，过滤结果
        if (ObjUtil.isNotEmpty(query.getElderName())) {
            filteredList = filteredList.stream()
                    .filter(vo -> ObjUtil.isNotEmpty(vo.getElderName()) && 
                            vo.getElderName().contains(query.getElderName()))
                    .collect(Collectors.toList());
        }

        // 手动分页
        int total = filteredList.size();
        int start = (query.getPageNum() - 1) * query.getPageSize();
        int end = Math.min(start + query.getPageSize(), total);
        
        List<PageBedByKeyVo> pageList = start < total ? filteredList.subList(start, end) : new ArrayList<>();

        // 构建返回结果
        Page<PageBedByKeyVo> resultPage = new Page<>(query.getPageNum(), query.getPageSize(), total);
        resultPage.setRecords(pageList);

        System.out.println("BedManageServiceImpl.pageBedByKey - 返回结果:");
        System.out.println("  total: " + total);
        System.out.println("  pageList size: " + pageList.size());
        System.out.println("  resultPage records size: " + resultPage.getRecords().size());

        return Result.success(resultPage);
    }

    @Override
    public Result listIdleBeds(Long elderId) {
        List<Bed> idleBeds = bedFunc.listIdleBed();
        
        // 如果指定了老人ID，需要包含该老人当前占用的床位（用于调换床位）
        if (elderId != null) {
            Elder elder = elderFunc.getElderById(elderId);
            if (elder != null && elder.getBedId() != null) {
                Bed currentBed = bedFunc.getBedById(elder.getBedId());
                if (currentBed != null) {
                    // 检查当前床位是否已经在空闲列表中
                    boolean alreadyInList = idleBeds.stream()
                            .anyMatch(bed -> Objects.equals(bed.getId(), currentBed.getId()));
                    
                    // 如果不在列表中，添加进去
                    if (!alreadyInList) {
                        idleBeds.add(currentBed);
                    }
                }
            }
        }
        
        // 获取相关数据用于构建完整的床位信息
        List<Building> buildingList = buildingFunc.listNotDelBuilding();
        List<Floor> floorList = floorFunc.listNotDelFloor();
        List<Room> roomList = roomFunc.listNotDelRoom();
        
        // 构建PageBedByKeyVo列表
        List<PageBedByKeyVo> idleBedVos = new ArrayList<>();
        for (Bed bed : idleBeds) {
            PageBedByKeyVo vo = BeanUtil.toBean(bed, PageBedByKeyVo.class);
            
            // 查找对应的房间、楼层、楼栋信息
            Room room = roomList.stream()
                    .filter(r -> Objects.equals(r.getId(), bed.getRoomId()))
                    .findFirst()
                    .orElse(null);
            
            if (room != null) {
                vo.setRoomName(room.getName());
                
                Floor floor = floorList.stream()
                        .filter(f -> Objects.equals(f.getId(), room.getFloorId()))
                        .findFirst()
                        .orElse(null);
                
                if (floor != null) {
                    vo.setFloorName(floor.getName());
                    
                    Building building = buildingList.stream()
                            .filter(b -> Objects.equals(b.getId(), floor.getBuildingId()))
                            .findFirst()
                            .orElse(null);
                    
                    if (building != null) {
                        vo.setBuildingName(building.getName());
                    }
                }
            }
            
            idleBedVos.add(vo);
        }
        
        return Result.success(idleBedVos);
    }



    @Override
    public Result editBed(OperateBedQuery query) {
        // 验证换床参数
        AssertUtil.notNull(query.getCurrentBedId(), ExceptionEnum.PARAM_ERROR);
        AssertUtil.notNull(query.getTargetBedId(), ExceptionEnum.PARAM_ERROR);
        
        // 验证当前床位是否存在且被占用
        Bed currentBed = bedMapper.selectById(query.getCurrentBedId());
        AssertUtil.notNull(currentBed, ExceptionEnum.BED_NULL);
        AssertUtil.isTrue(Objects.equals(currentBed.getBedFlag(), BedEnum.ENTER.getStatus()), 
                ExceptionEnum.BED_NOT_OCCUPY);
        
        // 验证目标床位是否存在且空闲
        Bed targetBed = bedMapper.selectById(query.getTargetBedId());
        AssertUtil.notNull(targetBed, ExceptionEnum.BED_NULL);
        AssertUtil.isTrue(Objects.equals(targetBed.getBedFlag(), BedEnum.IDLE.getStatus()), 
                ExceptionEnum.BED_OCCUPY);
        
        // 查找占用当前床位的老人
        List<Elder> elderList = elderFunc.listLiveElder(null);
        Elder occupiedElder = elderList.stream()
                .filter(elder -> Objects.equals(elder.getBedId(), query.getCurrentBedId()))
                .findFirst()
                .orElse(null);
        
        AssertUtil.notNull(occupiedElder, ExceptionEnum.BED_NOT_OCCUPY);
        
        // 执行换床操作
        // 1. 将老人移动到目标床位
        occupiedElder.setBedId(query.getTargetBedId());
        elderFunc.updateById(occupiedElder);
        
        // 2. 更新床位状态
        currentBed.setBedFlag(BedEnum.IDLE.getStatus()); // 原床位变为空闲
        targetBed.setBedFlag(BedEnum.ENTER.getStatus()); // 目标床位变为已入住
        
        // 3. 保存床位状态
        bedMapper.updateById(currentBed);
        bedMapper.updateById(targetBed);
        
        return Result.success();
    }



    @Override
    public Result getBedById(Long bedId) {
        Bed bed = bedMapper.selectById(bedId);
        AssertUtil.notNull(bed, ExceptionEnum.BED_NULL);
        return Result.success(bed);
    }

    @Override
    public Result listRooms() {
        return Result.success(roomFunc.listNotDelRoom());
    }

    @Override
    public Result listBuildings() {
        return Result.success(buildingFunc.listNotDelBuilding());
    }

    @Override
    public Result listFloors(Long buildingId) {
        return Result.success(floorFunc.listNotDelFloorByBuildingId(buildingId));
    }

    @Override
    public Result listRoomTypes() {
        return Result.success(roomTypeFunc.listNotDelRoomType(null));
    }

    @Override
    public Result listBedStatus() {
        List<DropDown> statusList = new ArrayList<>();
        for (BedEnum bedEnum : BedEnum.values()) {
            DropDown dropDown = new DropDown();
            dropDown.setId(Long.valueOf(statusList.size() + 1));
            dropDown.setName(bedEnum.getStatus());
            statusList.add(dropDown);
        }
        return Result.success(statusList);
    }

    @Override
    public Result listElders() {
        List<Elder> elderList = elderFunc.listLiveElder(null);
        List<DropDown> dropDownList = elderList.stream().map(elder -> {
            DropDown dropDown = new DropDown();
            dropDown.setId(elder.getId());
            dropDown.setName(elder.getName());
            return dropDown;
        }).collect(Collectors.toList());
        return Result.success(dropDownList);
    }

    @Override
    public Result unassignBed(Long bedId) {
        // 验证床位是否存在
        Bed bed = bedMapper.selectById(bedId);
        AssertUtil.notNull(bed, ExceptionEnum.BED_NULL);

        // 验证床位是否被占用
        AssertUtil.notTrue(Objects.equals(bed.getBedFlag(), BedEnum.IDLE.getStatus()), 
                ExceptionEnum.BED_NOT_OCCUPY);

        // 查找占用该床位的老人
        List<Elder> elderList = elderFunc.listLiveElder(null);
        Elder occupiedElder = elderList.stream()
                .filter(elder -> Objects.equals(elder.getBedId(), bedId))
                .findFirst()
                .orElse(null);

        if (occupiedElder != null) {
            // 清除老人的床位ID
            occupiedElder.setBedId(null);
            elderFunc.updateById(occupiedElder);
        }

        // 更新床位状态为空闲
        bed.setBedFlag(BedEnum.IDLE.getStatus());
        int result = bedMapper.updateById(bed);
        AssertUtil.isTrue(result > 0, ExceptionEnum.UPDATE_ERROR);

        return Result.success();
    }
} 